import os
import sys
import platform
import re
from os.path import join, dirname, abspath

pwd = os.getcwd()
path = os.path.abspath(os.path.join(pwd, os.pardir, os.pardir)) + os.sep
curPath = pwd

os.system( "scons -C ../../misc/autogen")

root_dir           = dirname(File('SConstruct').rfile().abspath)
client_include_dir = join(root_dir, path + 'client/CPP/include')
client_include     = join(root_dir, path + 'SequoiaDB/engine/include')
common_include_dir = join(root_dir, path + 'SequoiaDB/engine/client')
bson_include_dir   = join(root_dir, path + 'SequoiaDB/engine/bson')
boost_dir          = join(root_dir, path + 'thirdparty/boost')
boost_lib_dir      = join(boost_dir, 'lib')

options = {}
options_topass = {}

def GuessOS():
   id = platform.system()
   if id == 'Linux':
      return 'linux'
   elif id == 'Windows' or id == 'Microsoft':
      return 'win32'
   else:
      return None

def GuessArch():
   id = platform.machine()
   id = id.lower()
   if (not id) or (not re.match('(x|i[3-6])86$', id) is None):
      return 'ia32'
   elif id == 'i86pc':
      return 'ia32'
   elif id == 'x86_64':
      return 'ia64'
   elif id == 'amd64':
      return 'ia64'
   elif id == 'ppc64' :
      return 'ppc64'
   else:
      return None

guess_os = GuessOS()
guess_arch = GuessArch()

if guess_os == 'linux':
   ver = sys.version_info[0]
   sub = sys.version_info[1]
   python_include = sys.prefix + '/include/' + ("python%d.%d" % (ver, sub))
   python_lib = sys.prefix + '/lib/' + ("python%d.%d" % (ver, sub))
elif guess_os == 'win32':
   python_include = sys.prefix + "/include/"
   python_lib = sys.prefix + '/libs/'

def add_option( name, help , nargs , contibutesToVariantDir , dest=None ):
   if dest is None:
      dest = name

   AddOption( "--" + name,
              dest=dest,
              type="string",
              nargs=nargs,
              action="store",
              help=help )

   options[name] = { "help" : help,
                     "nargs" : nargs,
                     "contibutesToVariantDir" : contibutesToVariantDir,
                     "dest" : dest }

def get_option( name ):
   return GetOption( name )

def _has_option( name ):
   x = get_option( name )
   if x is None:
      return False

   if x == False:
      return False

   if x == "":
      return False

   return True

def has_option( name ):
   x = _has_option(name)

   if name not in options_topass:
   # if someone already set this, don't overwrite
      options_topass[name] = x

   return x

def get_variant_dir():

   a = []

   for name in options:
      o = options[name]
      if not has_option( o["dest"] ):
         continue
      if not o["contibutesToVariantDir"]:
         continue

      if o["nargs"] == 0:
         a.append( name )
      else:
         x = get_option( name )
         x = re.sub( "[,\\\\/]" , "_" , x )
         a.append( name + "_" + x )

   s = "#build/${PYSYSPLATFORM}/"

   if len(a) > 0:
      a.sort()
      s += "/".join( a ) + "/"
   else:
      s += "normal/"
   return s

add_option( "dd", "debug build no optimization, additional debug logging, etc...",
            0 , True , "debugBuildAndLogging" )

debugBuild = has_option( "debugBuildAndLogging" )

variantDir = get_variant_dir()
env = Environment( BUILD_DIR=variantDir )

env.Append ( CPPDEFINES=[ "SDB_DLL_BUILD" ] )
env.Append ( CPPDEFINES=[ "SDB_CLIENT" ] )
if guess_os == "win32":
   # check VC compiler
   for pathdir in env['ENV']['PATH'].split(os.pathsep):
      if os.path.exists(os.path.join(pathdir, 'cl.exe')):
         print( "found visual studio at " + pathdir )
         break
      else:
         #use current environment
         env['ENV'] = dict(os.environ)

   env.Append( CPPDEFINES=["HAVE_SOCKLEN_T",
               "WIN32", "NDEBUG", "_USRDLL", "_MBCS", "_EXPORTS",
               "COMPILE_DL_SEQUOIADB", "HAVE_SEQUOIADB=1"] ) # 

   winLibString = "ws2_32.lib kernel32.lib advapi32.lib Psapi.lib"
   winLibString += " user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib "
   winLibString += " odbc32.lib odbccp32.lib uuid.lib dbghelp.lib "

   env.Append( LIBS=Split(winLibString) )
   env.Append( CPPDEFINES=[ "_UNICODE" ] )
   env.Append( CPPDEFINES=[ "UNICODE" ] )

   if guess_arch == "ia64":
      env.Append( LIBPATH=[join(boost_lib_dir,'win64')] )
   else:
      env.Append( CPPDEFINES=[ "_USE_32BIT_TIME_T=1"])
      env.Append( LIBPATH=[join(boost_lib_dir,'win32')] )

   env.Append( CPPDEFINES=[ "_CRT_RAND_S" ] )
   env.Append( CPPFLAGS=" /EHsc /W3 " )
   if debugBuild:
      env.Append( CPPFLAGS=" /RTC1 /MDd /Z7 /errorReport:none " )
      env.Append( LINKFLAGS=" /debug " )
      env.Append( CPPFLAGS=" /Od " )
      env.Append( LINKFLAGS=" /NODEFAULTLIB:MSVCPRT  /NODEFAULTLIB:MSVCRT  " )

   else:
      env.Append( CPPDEFINES=[ "NDEBUG" ] )
      env.Append( CPPFLAGS= " /O2 /Gy " )
      env.Append( CPPFLAGS= " /MT /Zi /errorReport:none " )
      env.Append( CPPFLAGS= " /GL " )
      env.Append( LINKFLAGS=" /LTCG " )
      env.Append( LINKFLAGS=" /DEBUG " )
      env.Append( LINKFLAGS=" /NODEFAULTLIB:MSVCPRT  " )

   env.Append( CPPDEFINES=["_CONSOLE", "_CRT_SECURE_NO_WARNINGS", "PSAPI_VERSION=1", "_CRT_RAND_S" ] )

elif guess_os == "linux":
   env.Append( CPPDEFINES=["HAVE_CONFIG_H","PIC"])
   env['ENV']['HOME']=os.environ['HOME']
   env['ENV']['TERM']=os.environ['TERM']
   env.Append( CPPFLAGS="-ggdb" )
   if guess_arch == "ia64":
      env.Append( LIBPATH="/usr/lib64")
      env.Append( LIBPATH="/lib64")
      env.Append( LIBPATH=[join(boost_lib_dir,'linux64')] )
   elif guess_arch == "ia32":
      env.Append( LIBPATH="/usr/lib")
      env.Append( LIBPATH="/lib")
      env.Append( LIBPATH=[join(boost_lib_dir,'linux32')] )
   elif guess_arch == 'ppc64':
      env.Append( CPPDEFINES=[ "SDB_BIG_ENDIAN" ] )
      env.Append( LIBPATH="/usr/lib64")
      env.Append( LIBPATH="/lib64")
      env.Append( LIBPATH=[join(boost_lib_dir,'ppclinux64')] )
   if debugBuild:
      env.Append( CPPFLAGS=" -O0 -fstack-protector")
      env['ENV']['GLIBCXX_FORCE_NEW']=1
   else:
      env.Append( CPPFLAGS=" -O3")

env.Append( CPPPATH=[ root_dir, client_include, boost_dir,
                      common_include_dir, bson_include_dir, python_include ] )
env.Append( LIBPATH= python_lib)

Export("env")
Export("path")
Export("curPath")

# exec build scons
env.SConscript( 'SConscript', variant_dir=variantDir, duplicate=False )
